/* Copyright (c) 2010-2020 Vadim Surov.
 */
package com.srv.client.widget;

import java.util.Date;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.resources.client.ClientBundle;
import com.sencha.gxt.core.client.Style.SelectionMode;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.dnd.core.client.DND.Feedback;
import com.sencha.gxt.dnd.core.client.DND.Operation;
import com.sencha.gxt.dnd.core.client.DndDragStartEvent;
import com.sencha.gxt.dnd.core.client.ListViewDragSource;
import com.sencha.gxt.dnd.core.client.ListViewDropTarget;
import com.sencha.gxt.widget.core.client.ContentPanel;
import com.sencha.gxt.widget.core.client.ListView;
import com.sencha.gxt.widget.core.client.ListViewCustomAppearance;
import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent;
import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent.SelectionChangedHandler;
import com.srv.shared.Card;
import com.srv.shared.Control;
import com.srv.shared.ControlProperties;

public class CardPanel extends ContentPanel  {

	private ListView<Control, Control> listView; 
	private ListStore<Control> store;

	private int floating = 0;

//	/**
//	 * A custom {@link Cell} used to render a {@link Contact}. We extend
//	 * {@link AbstractCell} because it provides reasonable implementations of
//	 * methods that work for most use cases.
//	 */
//	private class DesignControlCell extends AbstractCell<Control> {
//
//		private String name;
//
//		public DesignControlCell(String name) {
//			// Our cell responds to click event, change events and keydown events.
//			super("click", "change", "keydown");
//
//			this.name = name;
//		}
//
//		@Override
//		public void onBrowserEvent(Context context, Element parent, Control control,
//				NativeEvent event, ValueUpdater<Control> valueUpdater) {
//			// Check that the value is not null.
//			if (control == null) {
//				return;
//			}
//
//			// Call the super handler, which handlers the enter key.
//			super.onBrowserEvent(context, parent, control, event, valueUpdater);
//
//			// Handle click events.
//			if ("change".equals(event.getType())) {
//				updateChecked(parent, control);
//			} 			
//			// On click, perform the same action that we perform on enter.
//			else if ("click".equals(event.getType())) {
////				Window.alert("You clicked " + control.getValue());
////		        this.onEnterKeyDown(context, parent, control, event, valueUpdater);
////				this.
//			}			
//		}
//
//		/**
//		 * By convention, cells that respond to user events should handle the enter
//		 * key. This provides a consistent user experience when users use keyboard
//		 * navigation in the widget. Our cell will toggle the checkbox on Enter.
//		 */
//		@Override
//		protected void onEnterKeyDown(Context context, Element parent,
//				Control control, NativeEvent event, ValueUpdater<Control> valueUpdater) {
//			// Toggle the checkbox.
//			InputElement input = getInputElement(parent);
//			input.setChecked(!input.isChecked());
//
//			// Update the favorites based on the new state.
//			updateChecked(parent, control);
//
//		}
//
//		@Override
//		public void render(Context context, Control control, SafeHtmlBuilder sb) {
//			/*
//			 * Always do a null check on the value. Cell widgets can pass null to
//			 * cells if the underlying data contains a null, or if the data arrives
//			 * out of order.
//			 */
//			if (control == null) {
//				return;
//			}
//
//			sb.appendHtmlConstant(control.getHtml(name));
//			
//			Info.display("", "rendered");
//			
//		}
//
//		/**
//		 * Get the checkbox input element from the parent element that wraps our
//		 * cell.
//		 * 
//		 * @param parent the parent element
//		 * @return the checkbox
//		 */
//		private InputElement getInputElement(Element parent) {
//			// We need to navigate down to our input element.
//			//TableElement table = parent.getFirstChildElement().cast();
//			//TableRowElement tr = table.getRows().getItem(0);
//			//TableCellElement td = tr.getCells().getItem(0);
//			//InputElement input = td.getFirstChildElement().cast();
//			final InputElement input = parent.getFirstChildElement().cast();
//			return input;
//		}
//
//		/**
//		 * Update the favorites list based on the state of the input element.
//		 */
//		private void updateChecked(Element parent, Control control) {
//			// Get the input element.
//			//final InputElement input = getInputElement(parent);
//
//			if (control.getType() == Control.Type.Radio) {
//				final List<Control> controls = store.getAll();
//				for(Control c : controls)
//					c.setValue("unchecked");
//			}
//
//			// Update the favorites based on the checked state.
//			if (control.getValue().equals("unchecked"))
//				control.setValue("checked");
//			else
//				control.setValue("unchecked");
//
//		}
//	}

	interface Resources extends ClientBundle {
		@Source("ListView.css")
		Style css();
	}

	interface Style extends CssResource {
		String over();
		String select();
		String thumb();
		String thumbWrap();
	}

	interface Resources1 extends ClientBundle {
		@Source("ListView1.css")
		Style1 css();
	}

	interface Style1 extends CssResource {
		String over1();
		String select1();
		String thumb1();
		String thumbWrap1();
	}

	public CardPanel(Card card) {
		super();
		setHeaderVisible(false);
		setBodyBorder(false);
		setBorders(false);
		setCard(card);
	}

	public void setCard(final Card card) {
		final ControlProperties props = GWT.create(ControlProperties.class);

		store = new ListStore<Control>(props.key())	{{
			for (Control control : card.getControls())
				add(control);
		}};

		floating = card.getFloating();

		if (floating==0) {
			final Resources resources = GWT.create(Resources.class);
			resources.css().ensureInjected();
			final Style style = resources.css();

			listView = new ListView<Control, Control>(store, props.getControl(), 
					new ListViewCustomAppearance<Control>("." + style.thumbWrap(), style.over(), style.select()) 
					{
				@Override
				public void renderItem(SafeHtmlBuilder builder, SafeHtml content) {
					builder.appendHtmlConstant("<div class='" + style.thumbWrap() + "'>");
					builder.append(content);
					builder.appendHtmlConstant("</div>");
				}
					}
					); 
		} else if (floating==1) {
			final Resources1 resources = GWT.create(Resources1.class);
			resources.css().ensureInjected(); 
			final Style1 style = resources.css();

			listView = new ListView<Control, Control>(store, props.getControl(), 
					new ListViewCustomAppearance<Control>("." + style.thumbWrap1(), style.over1(), style.select1()) 
					{
				@Override
				public void renderItem(SafeHtmlBuilder builder, SafeHtml content) {
					builder.appendHtmlConstant("<div class='" + style.thumbWrap1() + "'>");
					builder.append(content);
					builder.appendHtmlConstant("</div>");
				}
					}
					); 
		};

		
		listView.setCell(new TextAreaEditCell("card_"+new Date().getTime()));
//		listView.setCell(new DesignControlCell("card_"+new Date().getTime()));

		listView.getSelectionModel().setLocked(true); //.setSelectionMode(SelectionMode.SINGLE);
		listView.getSelectionModel().addSelectionChangedHandler(new SelectionChangedHandler<Control>() {

			@Override
			public void onSelectionChanged(SelectionChangedEvent<Control> event) {
				CardPanel.this.onSelectionChange(event);
			}
		});

		new ListViewDragSource<Control>(listView) {
			{
				setGroup("movecontrol");
			}
			@Override
			protected void onDragStart(DndDragStartEvent event) {
				super.onDragStart(event);
				// by default drag is allowed
				final Control control = listView.getSelectionModel().getSelection().get(0);
				event.getStatusProxy().update(control.getDragIcon());
			}
		};	        

		new ListViewDropTarget<Control>(listView) {
			{
				setGroup("movecontrol");
				setFeedback(Feedback.INSERT);
				setOperation(Operation.COPY);
				setAllowSelfAsSource(true); 
			}
		};	        

		setWidget(listView);
	}

	private void onSelectionChange(SelectionChangedEvent<Control> se) {
		if (se.getSelection().size() > 0) {
			final Control control = se.getSelection().get(0);
		}	
	}

	public Card getCard() {
		final List<Control> controls = store.getAll();
		return new Card(floating, controls);
	}	

}
